import asyncio
import os

import wx
from cefpython3 import cefpython as cef
from loguru import logger
from wxasync import StartCoroutine

cefd = cef.GetModuleDirectory()
logger.debug(cefd)
if cefd.endswith("cefpython3"):
    resources_dir_path = cefd
else:
    resources_dir_path = cefd + "/cefpython3"
locales_dir_path = resources_dir_path + '/locales'

_ = wx.GetTranslation


class HtmlDialog(wx.Dialog):
    def __init__(self, parent, ctr, url, name='HtmlDialog', title=_('Html page'), width=800, height=600):
        self.ctr = ctr
        wx.Dialog.__init__(self, name=name, parent=parent, title=title)
        self._init_cef()
        self._init_browser()
        self._init_event()

    def _init_cef(self):
        # sys.excepthook = cef.ExceptHook

        settings = {
            "resources_dir_path": resources_dir_path,
            'locales_dir_path': locales_dir_path,
            "browser_subprocess_path": os.path.join(resources_dir_path, "subprocess.exe"),
            "locale": "zh-CN"}
        if wx.Platform == "__WXMAC__":
            settings['external_message_pump'] = True
        if wx.Platform == "__WXMSW__":
            cef.DpiAware.EnableHighDpiSupport()
        if wx.Platform == "__WXGTK__":
            cef.WindowUtils.InstallX11ErrorHandlers()
        if wx.Platform == "__WXMSW__":
            wx.CallAfter(self._fix_keyboard)
        cef.Initialize(settings=settings)

    def _init_browser(self):
        window_info = cef.WindowInfo()
        (width, height) = self.GetClientSize().Get()
        window_info.SetAsChild(self.GetHandle(), [0, 0, width, height])
        self.browser = cef.CreateBrowserSync(window_info)

    def _init_event(self):
        self.Bind(wx.EVT_CLOSE, self._on_close)
        self.Bind(wx.EVT_SIZE, self._on_size)
        self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)

        # self.timer = wx.Timer(self)
        # self.timer.Start(10)
        # self.Bind(wx.EVT_TIMER, self._on_timer, self.timer)
        self.running = True
        StartCoroutine(self._on_timer(), self)

    def _fix_keyboard(self):
        ctrl = self
        while ctrl:
            ctrl.SetWindowStyle(ctrl.GetWindowStyle() & ~wx.TAB_TRAVERSAL)
            ctrl = ctrl.GetParent()

    def _on_set_focus(self, _):
        if wx.Platform == "__WXMSW__":
            cef.WindowUtils.OnSetFocus(self.GetHandle(), 0, 0, 0)
        self.browser.SetFocus(True)

    def _on_size(self, _):
        if wx.Platform == "__WXMSW__":
            cef.WindowUtils.OnSize(self.GetHandle(), 0, 0, 0)
        self.browser.NotifyMoveOrResizeStarted()

    async def _on_timer(self):
        while self.running:
            cef.MessageLoopWork()
            await asyncio.sleep(0.02)

    def _on_close(self, e):
        if wx.Platform == "__WXMAC__":
            self.browser.CloseBrowser()
            self.browser = None
            self.Destroy()
            cef.Shutdown()
        else:
            self.running = False
            # self.timer.Stop()
            # self.browser.ParentWindowWillClose()
            self.browser = None

            e.Skip()

    def __del__(self):
        cef.Shutdown()

    def load_url(self, url):
        self.browser.LoadUrl(url)
